package com.zk.bytecode.intercept;

import com.zk.bytecode.trace.InMemorySaver;
import com.zk.bytecode.trace.StackTraceManagement;
import com.zk.bytecode.trace.TraceInterceptor;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;

import static net.bytebuddy.matcher.ElementMatchers.isDefaultMethod;
import static net.bytebuddy.matcher.ElementMatchers.isVirtual;

/**
 * 执行什么
 */
public class ProducerMain {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        enhanced();
        execute();

    }

    private static void enhanced()  {
        ByteBuddyAgent.install();

        AsmVisitorWrapper visitWrapper = new AsmVisitorWrapper.ForDeclaredMethods()
                .method(isVirtual().or(isDefaultMethod())
                        , Advice.to(TraceInterceptor.class)
                );

        new ByteBuddy().redefine(Producer.class)
                .visit(visitWrapper)
                .make()
                .load(ClassLoader.getSystemClassLoader(), ClassReloadingStrategy.fromInstalledAgent())
                .getLoaded();
        new ByteBuddy().redefine(DataProducer.class)
                .visit(visitWrapper)
                .make()
                .load(ClassLoader.getSystemClassLoader(), ClassReloadingStrategy.fromInstalledAgent())
                .getLoaded();

    }

    private static void execute() {
        new DataProducer().create();
        StackTraceManagement holder = InMemorySaver.getHolder();
        System.out.println(holder);
    }
}
